
#ifdef INT
#  define TYP INTEGER
#else
#ifdef FLOAT
#  define TYP REAL
#else
#error "Need to give MACRO definition for element type : -DTYPE_INT or -DTYPE_FLOAT"
#endif
#endif


	PROGRAM PROG_PRINC
	!
	!compilation : gfortran prog_princ.f90 -fbounds-check
	!
	IMPLICIT NONE
	!DECLARATION DES PARAMETRES


	! LA TAILLE DES MATRICES EST ENTREE EN LIGNE DE COMMANDE LORS DE L' EXECUTION
	INTEGER :: p

	INTEGER :: DIM1
	INTEGER :: F_COMPTEUR
	INTEGER :: I,J
	INTEGER :: NBBANDESUP,NBBANDEINF,N
	TYP :: S

	REAL :: INTERMEDIAIRE
	INTEGER :: VALEURMAX,VALEURMIN
	

	CHARACTER(len=32) :: arg

	!********************POUR LE STOCKAGE BANDE
	TYP, DIMENSION (:,:), ALLOCATABLE :: BANDE

	TYP,DIMENSION(:),ALLOCATABLE :: U
	INTEGER :: IERR

	TYP,DIMENSION(:),ALLOCATABLE :: V

	!**lecture des arguments en ligne de commande
	DO P=0,2
		CALL get_command_argument(p, arg)
		IF (LEN_TRIM(arg) == 0) exit 
		!WRITE (*,*) TRIM(arg)
		IF (p == 1) THEN
			read ( arg , '(i10)') DIM1
		ELSEIF (p == 2) THEN
			read ( arg , '(i10)') F_COMPTEUR
		ENDIF
	END DO

	NBBANDESUP=0
	NBBANDEINF=0
	N=NBBANDESUP+NBBANDEINF+1

	!********************POUR LE STOCKAGE BND
	ALLOCATE (BANDE(DIM1,N),STAT=IERR)

	ALLOCATE (U(DIM1))
	ALLOCATE (V(DIM1))


	IF(IERR.NE.0) STOP 'ERREUR pour l allocation des matrices/vecteurs!'


	VALEURMAX=100000
	VALEURMIN=-100000
	! PRENONS A DIAGONALE (COEFF ALEATOIRES)
	DO I=1,DIM1
		CALL RANDOM_NUMBER(INTERMEDIAIRE)
		BANDE(I,1)=INTERMEDIAIRE*(VALEURMAX-VALEURMIN)+VALEURMIN		
		U(I)=I
	END DO

	!APPEL DES SUBROUTINES  
	CALL SPMV_BND(BANDE,U,V,DIM1,NBBANDEINF,NBBANDESUP,F_COMPTEUR)

	! ON DESALLOUE TOUT CE QU'ON A ALLOUE
	DEALLOCATE(U)
	DEALLOCATE(V)
	DEALLOCATE(BANDE)

	!END DO

!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------ESPACE SUBROUTINES------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
CONTAINS


!SUBROUTINES MATRICE CREUSE BND

!-----------------------------------------------------------------------------
! Fonction : SPMV_BND
! Description :- calcul le produit matrice_creuse/vecteur et enregistre le temps d'execution et les parametre de la matrice dans un fichier
!                pour un stockage creux du type Ellpack_Itpack, on a 2 tableaux de tailles dim*Nmax, dont un stocke les valeurs des coefficients non nuls par ligne
!                et un tableau qui contient les numéros de colonne des elements non nuls
!              - T **AA stocke les valeurs des coefficients non nuls par ligne
!              - T *u, le vecteur multiplie
!              - T *v, le vecteur resultat
! 			   - int dim la dimension de la matrice
!              - Nmax = max(Nmax[i]) avec Nmax(i], le nombre maximum de valeurs non nuls sur la ligne i
! Retour: aucun
!-----------------------------------------------------------------------------  
SUBROUTINE SPMV_BND(BANDE,U,V,DIM1,NBBANDEINF,NBBANDESUP,F_COMPTEUR)
!DECLARATIONS PARAMETRES
REAL *8:: T1,T2,TEMPS_MOY=0.0
INTEGER :: I,K,MAXI,MINI,COMPTEUR=0
CHARACTER*50 :: FORME="stockage BaNDe"
INTEGER, INTENT (IN) :: DIM1,NBBANDEINF,NBBANDESUP,F_COMPTEUR
TYP,DIMENSION(:), INTENT (IN) :: U
TYP, DIMENSION (:,:), INTENT (IN) :: BANDE
TYP,DIMENSION(:), INTENT (OUT):: V


!CALCUL PRODUIT
DO COMPTEUR=1,F_COMPTEUR

!TOP CHRONO
CALL CPU_TIME(T1)
DO I=1,DIM1
DO K=1,NBBANDEINF+NBBANDESUP+1
	MAXI=MAX(K,K+I-NBBANDEINF)
	MINI=MIN(MAXI,DIM1)
	V(I)=V(I)+BANDE(I,K)*U(MINI)
END DO
END DO
!       WRITE (6,*) V(I)
!STOP CHRONO 
CALL CPU_TIME(T2)

TEMPS_MOY=T2 -T1+TEMPS_MOY
END DO
TEMPS_MOY=TEMPS_MOY/F_COMPTEUR
WRITE(*,*) TEMPS_MOY



END SUBROUTINE SPMV_BND

!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------END SUBROUTINES------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------------------------

END PROGRAM PROG_PRINC

!------------------------------------------------------------------------------
!MESSAGE D'ERREUR RETOURNER DANS LE TERMINAL
!a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
!Abandon  svn commit -m "projet au 02/07/12 script.sh : corrections des repetitions des caracteristiques cpu, main_dense_2D et 1D : correction erreur nan, prog_fortran : ajout du f_compteur en parametre"




!--------------------------------------------------------------------------------------

